﻿using System;
using System.Reflection;
using UnityEngine;

namespace YunHao
{

    /// <summary>
    /// PlayerPrefs 加密
    /// </summary>
    public class PlayerPrefsControl
    {
        /// <summary>
        /// 保存对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="data"></param>
        public static void SaveObject<T>(string key, T data)
        {
            Type t = typeof(T);
            FieldInfo[] fields = t.GetFields();
            foreach (var field in fields)
            {
                string saveName = string.Format("{0}_{1}.{2}", key, t.Name, field.Name);
                switch (field.FieldType.Name)
                {
                    case "String":
                        SetString(saveName, field.GetValue(data).ToString());
                        break;
                    case "Int32":
                    case "Int64":
                    case "Int":
                    case "uInt":
                        SetInt(saveName, (int)field.GetValue(data));
                        break;
                    case "Float":
                        SetFloat(saveName, (float)field.GetValue(data));
                        break;
                }
            }
        }

        /// <summary>
        /// 读取对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="data"></param>
        public static T GetObject<T>(string key) where T : new()
        {
            T result = new T();
            Type t = typeof(T);
            FieldInfo[] fields = t.GetFields();
            foreach (var field in fields)
            {
                string saveName = string.Format("{0}_{1}.{2}", key, t.Name, field.Name);
                switch (field.FieldType.Name)
                {
                    case "String":
                        field.SetValue(result, GetString(saveName));
                        break;
                    case "Int32":
                    case "Int64":
                    case "Int":
                    case "uInt":
                        field.SetValue(result, GetInt(saveName));
                        break;
                    case "Float":
                        field.SetValue(result, GetFloat(saveName));
                        break;
                }
            }
            return result;
        }

        /// <summary>
        /// 设置int
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public static void SetInt(string key, int val)
        {
            PlayerPrefs.SetString(CryptoString.GetHash(key), CryptoString.Encrypt(val.ToString()));
        }

        /// <summary>
        /// 获取int
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static int GetInt(string key, int defaultValue = 0)
        {
            string @string = GetString(key, defaultValue.ToString());
            int result = defaultValue;
            int.TryParse(@string, out result);
            return result;
        }

        /// <summary>
        /// 设置float
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public static void SetFloat(string key, float val)
        {
            PlayerPrefs.SetString(CryptoString.GetHash(key), CryptoString.Encrypt(val.ToString()));
        }

        /// <summary>
        /// 获取float
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static float GetFloat(string key, float defaultValue = 0f)
        {
            string @string = GetString(key, defaultValue.ToString());
            float result = defaultValue;
            float.TryParse(@string, out result);
            return result;
        }

        /// <summary>
        /// 设置string
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public static void SetString(string key, string val)
        {
            PlayerPrefs.SetString(CryptoString.GetHash(key), CryptoString.Encrypt(val));
        }

        /// <summary>
        /// 获取string
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static string GetString(string key, string defaultValue = "")
        {
            string text = defaultValue;
            string @string = PlayerPrefs.GetString(CryptoString.GetHash(key), defaultValue.ToString());
            if (!text.Equals(@string))
            {
                text = CryptoString.Decrypt(@string);
            }
            return text;
        }

        /// <summary>
        /// 是否存在当前key的PlayerPrefs
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool HasKey(string key)
        {
            string hash = CryptoString.GetHash(key);
            return PlayerPrefs.HasKey(hash);
        }

        /// <summary>
        /// 删除指定key的PlayerPrefs
        /// </summary>
        /// <param name="key"></param>
        public static void DeleteKey(string key)
        {
            string hash = CryptoString.GetHash(key);
            PlayerPrefs.DeleteKey(hash);
        }

        /// <summary>
        /// 删除所有PlayerPrefs
        /// </summary>
        public static void DeleteAll()
        {
            PlayerPrefs.DeleteAll();
        }

        /// <summary>
        /// 保存 PlayerPrefs
        /// </summary>
        public static void Save()
        {
            PlayerPrefs.Save();
        }
    }
}